package com.devbobcorn.nekoration.entities;

import java.util.List;

import javax.annotation.Nullable;

import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.IPacket;
import net.minecraft.util.DamageSource;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.network.FMLPlayMessages;
import net.minecraftforge.fml.network.NetworkHooks;

public class ElectricArcEntity extends Entity {
	private int life;
	public long seed;
	private int flashes;
	private boolean visualOnly;
	@Nullable
	private ServerPlayerEntity cause;
	private float damage = 10.0F;

	public ElectricArcEntity(EntityType<ElectricArcEntity> type, World world) {
		// Constructor 1: the default one for server-side to create brand-new Entity Objects
		super(ModEntityType.$ELECTRIC_ARC_TYPE.get(), world);
		this.noCulling = true;
		this.life = 2;
		this.seed = this.random.nextLong();
		this.flashes = this.random.nextInt(3) + 1;
		LOGGER.info("Constructor #1 Called on " + (world.isClientSide ? "Client" : "Server"));
	}

	public ElectricArcEntity(FMLPlayMessages.SpawnEntity packet, World world){
		// Constructor 2: the one for client-side, creating instances with data packets from the Server
		// Enable by adding 'setCustomClientFactory' when building the entity type
		super(ModEntityType.$ELECTRIC_ARC_TYPE.get(), world);
		this.noCulling = true;
		this.life = 500;
		this.seed = this.random.nextLong();
		this.flashes = this.random.nextInt(3) + 1;
		LOGGER.info("Constructor #2 Called on " + (world.isClientSide ? "Client" : "Server"));
	}

	public void setVisualOnly(boolean visualOnly) {
		this.visualOnly = visualOnly;
	}

	public SoundCategory getSoundSource() {
		return SoundCategory.WEATHER;
	}

	public void setCause(@Nullable ServerPlayerEntity player) {
		this.cause = player;
	}

	public void setDamage(float damage) {
		this.damage = damage;
	}

	public float getDamage() {
		return this.damage;
	}

	public void tick() {
		super.tick();
		if (this.life == 2) {
			this.level.playSound((PlayerEntity) null, this.getX(), this.getY(), this.getZ(), SoundEvents.LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, 10000.0F, 0.8F + this.random.nextFloat() * 0.2F);
			this.level.playSound((PlayerEntity) null, this.getX(), this.getY(), this.getZ(), SoundEvents.LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F);
		}

		--this.life;
		if (this.life < 0) {
			if (this.flashes == 0) {
				this.remove();
			} else if (this.life < -this.random.nextInt(10)) {
				--this.flashes;
				this.life = 1;
				this.seed = this.random.nextLong();
			}
		}

		if (this.life >= 0) {
			if (!(this.level instanceof ServerWorld)) {
				this.level.setSkyFlashTime(2);
			} else if (!this.visualOnly) {
				List<Entity> list = this.level.getEntities(this, new AxisAlignedBB(this.getX() - 3.0D, this.getY() - 3.0D, this.getZ() - 3.0D, this.getX() + 3.0D, this.getY() + 6.0D + 3.0D, this.getZ() + 3.0D), Entity::isAlive);

				for(Entity entity : list){
					entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1);
					if (entity.getRemainingFireTicks() == 0) {
						entity.setSecondsOnFire(8);
					}
					entity.hurt(DamageSource.LIGHTNING_BOLT, this.getDamage());
				}

				if (this.cause != null)
					CriteriaTriggers.CHANNELED_LIGHTNING.trigger(this.cause, list);
			}
		}
	}

	@OnlyIn(Dist.CLIENT)
	public boolean shouldRenderAtSqrDistance(double dist) {
		double d0 = 64.0D * getViewScale();
		return dist < d0 * d0;
	}

	protected void defineSynchedData() { }

	protected void readAdditionalSaveData(CompoundNBT tag) { }

	protected void addAdditionalSaveData(CompoundNBT tag) { }

	@Override
	public IPacket<?> getAddEntityPacket() {
		IPacket<?> packet = NetworkHooks.getEntitySpawningPacket(this);
		return packet;
	}
}
